home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 227_01 / grafturt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-07  |  15.8 KB  |  592 lines

  1. /*
  2.  * g r a f t u r t . c
  3.  * -------------------
  4.  * This module implements the turtle graphics package. Note that this
  5.  * package always operates with its own, global coordinate system. The
  6.  * resulution may by set by the function call turt_res() and is predefined
  7.  * to 801 * 401, which should be a good value for many video devices.
  8.  *
  9.  * Realease history
  10.  * --------------
  11.  * Jun, 20. 1987    Begin implemention.
  12.  *
  13.  * Written by       Rainer Gerhards
  14.  *                  Petronellastr. 6
  15.  *                  D-5112 Baesweiler
  16.  *                  West Germany
  17.  *                  Phone (49) 2401 - 1601
  18.  */
  19.  
  20. /*
  21.  * Define library implemention mode - forbidden for user!
  22.  */
  23. #define LIB_MODE 1
  24.  
  25. #include <stdio.h>
  26. #include <dos.h>
  27. #include <math.h>
  28. #ifdef    __TURBOC__
  29. #include <conio.h>
  30. #endif
  31.  
  32. #include "graphics.h"
  33.  
  34. /*
  35.  * -------------------------------------------------------------------------
  36.  *                               M A C R O S
  37.  * -------------------------------------------------------------------------
  38.  */
  39. #define last3bit(x) ((x) &  0x0007)
  40. #define exclst3b(x) ((x) & ~0x0007)
  41.  
  42. #define DIR      turt_dir
  43. #define PEN_DN   turt_pdn
  44. #define PEN_UP   !turt_pdn
  45. #define X        turt_x
  46. #define Y        turt_y
  47. #define XC       convxco((double)turt_x)
  48. #define YC       convyco((double)turt_y)
  49. #define COLOR    turt_clr
  50. #define VISIBLE  turt_vis
  51. #define DELY_TIM turt_del
  52.  
  53. #define NXT_X(x, cnt, direct)\
  54.     ((x) + (float) itocarxc((convxdis(\
  55.                        convxrad(glo_maxx, glo_maxy,(cnt)))),\
  56.                (direct)))
  57. #define NXT_Y(y, cnt, direct)\
  58.     ((y) + (float) itocaryc((convydis((double) (cnt))), (direct)))
  59.  
  60.  
  61. /*
  62.  * -------------------------------------------------------------------------
  63.  *                  S T A T I C   D A T A   I T E M S
  64.  * -------------------------------------------------------------------------
  65.  */
  66. static int turt_dir = GTDHOME;        /* turtle direction in degrees    */
  67.  
  68.  
  69. /*
  70.  * -------------------------------------------------------------------------
  71.  *                          F U N C T I O N S
  72.  * -------------------------------------------------------------------------
  73.  */
  74.  
  75. #ifdef    USEPROTT
  76.     extern void    clr_turt(void);
  77.     extern void    set_turt(void);
  78. #endif
  79.  
  80. static void clr_turt()
  81. /*
  82.  * name          clr_turt
  83.  *
  84.  * synopsis      clr_turt();
  85.  *
  86.  * description   This function clear the old turtle symbol (if the turtle
  87.  *               is visible).
  88.  *
  89.  * Warning       This function is internal to the turtle system only. It
  90.  *               may be changed or removed without notice!
  91.  */
  92. {
  93. double tx, ty;                /* temporary turtle position    */
  94. int tdir;                /* temporary direction        */
  95.  
  96. if(VISIBLE == TRUE)
  97.     {
  98.     tx = NXT_X(X, (turt_sz/2.0), DIR);
  99.     ty = NXT_Y(Y, (turt_sz/2.0), DIR);
  100.     setwm(WM_INV);
  101.     if(PEN_DN)
  102.       line(XC, YC, convxco(tx), convyco(ty), WHITE);
  103.     if((tdir = DIR - 135) < 0)
  104.         tdir = 360 + tdir;
  105.     line(convxco(tx), convyco(ty),
  106.          (int) convxco(NXT_X(tx, -turt_sz, tdir)),
  107.          (int) convyco(NXT_Y(ty, -turt_sz, tdir)), WHITE
  108.         );
  109.     if((tdir = DIR + 135) > 360)
  110.         tdir -= 360;
  111.     line(convxco(tx), convyco(ty),
  112.          convxco(NXT_X(tx, -turt_sz, tdir)),
  113.          convyco(NXT_Y(ty, -turt_sz, tdir)), WHITE
  114.         );
  115.     setwm(WM_NORM);
  116.     }
  117. }
  118.  
  119.  
  120. static void set_turt()
  121. /*
  122.  * name          set_turt
  123.  *
  124.  * synopsis      set_turt();
  125.  *
  126.  * description   This function redraws the turtle symbol after the turtle
  127.  *               position has changed. If the turtle is invisible, no symbol
  128.  *               is drawn.
  129.  *               This function is also responsible for the turtle delay.
  130.  *
  131.  * Warning       This function is internal to the turtle system only. It
  132.  *               may be changed or removed without notice!
  133.  */
  134. {
  135. clr_turt();
  136. }
  137.  
  138.  
  139. void gt_show()
  140. /*
  141.  * name          gt_show
  142.  *
  143.  * synopsis     gt_show()
  144.  *
  145.  * description     The turtle is shown after each drawing operation if
  146.  *         this function is called.
  147.  */
  148. {
  149. clr_turt();
  150. VISIBLE = TRUE;
  151. set_turt();
  152. }
  153.  
  154.  
  155. void gt_hide()
  156. /*
  157.  * name          gt_show
  158.  *
  159.  * synopsis     gt_show()
  160.  *
  161.  * description     The turtle isn't shown anytime after this function is called.
  162.  */
  163. {
  164. clr_turt();
  165. VISIBLE = FALSE;
  166. set_turt();
  167. }
  168.  
  169.  
  170. void gt_forwd(count)
  171. int count;
  172. /*
  173.  * name          gt_forwd
  174.  *
  175.  * synopsis      gt_forwd(count)
  176.  *               int count;      count to move foreward
  177.  *
  178.  * description   This function moves the turtle forward the specfied count
  179.  *               of 'logical' pixel (or backward, if negative).
  180.  */
  181. {
  182. double tx, ty;
  183.  
  184. clr_turt();  /* erase old turtle */
  185. tx = NXT_X(X, count, DIR);
  186. ty = NXT_Y(Y, count, DIR);
  187. if(PEN_DN)
  188.   line(XC, YC, convxco((double) tx), convyco((double) ty), COLOR);
  189. X = tx;
  190. Y = ty;
  191. set_turt(); /* mark new turtle position */
  192. }
  193.  
  194.  
  195. #if USEVOID
  196. void
  197. #endif
  198. gt_backw(count)
  199. int count;
  200. /*
  201.  * name          gt_backw
  202.  *
  203.  * synopsis      gt_backw(count)
  204.  *               int count;      count to move backward
  205.  *
  206.  * description   This function is the opposite to function gt_forwd.
  207.  *               It moves the turtle the specified position in backward
  208.  *               direction.
  209.  *               Internaly this results in a call to function gt_forwd,
  210.  *               and because this is so simple the function is available
  211.  *               as macro too. So you should use arguments without side-
  212.  *               effekt to be as portable as possible.
  213.  */
  214. {
  215. gt_forwd(-count);
  216. }
  217.  
  218.  
  219. #if USEVOID
  220. void
  221. #endif
  222. gt_dir(degrees)
  223. int degrees;
  224. /*
  225.  * name          gt_dir
  226.  *
  227.  * synopsis      gt_dir(degrees);
  228.  *               int degrees;      new turtle direction in degrees.
  229.  *
  230.  * description   This function sets the absolute turtle direction in
  231.  *               degrees for further moves. If the value contained in
  232.  *               "degrees" is invalid, it will be converted into the
  233.  *               range 0..359. Negative degrees will be correctly converted
  234.  *               to their positve counterpart.
  235.  */
  236. {
  237. int wasneg = 0;
  238.  
  239. clr_turt();  /* erase old turtle */
  240. degrees += 90;
  241. if(degrees < 0)
  242.   {
  243.   degrees = -degrees;
  244.   wasneg = -1;
  245.   }
  246. while(degrees > 359)
  247.   degrees -= 360;
  248. DIR = wasneg ? 360 - degrees : degrees;
  249. set_turt(); /* mark new turtle position */
  250. }
  251.  
  252.  
  253. #if USEVOID
  254. void
  255. #endif
  256. gt_tleft(degrees)
  257. int degrees;
  258. /*
  259.  * name          gt_tleft
  260.  *
  261.  * synopsis      gt_tleft(degrees);
  262.  *               int degrees;      turtle rotate count in degrees
  263.  *
  264.  * description   This function rotates the turtle in left direction, using
  265.  *               the rotate count specified in degrees. Negative counts mean
  266.  *               rotate to rigth position.
  267.  */
  268. {
  269. gt_dir(DIR + degrees - 90);
  270. }
  271.  
  272.  
  273. #if USEVOID
  274. void
  275. #endif
  276. gt_trght(degrees)
  277. int degrees;
  278. /*
  279.  * name          gt_trght
  280.  *
  281.  * synopsis      gt_tleft(degrees);
  282.  *               int degrees;      turtle rotate count in degrees
  283.  *
  284.  * description   This function rotates the turtle in rigth direction, using
  285.  *               the rotate count specified in degrees. Negative counts mean
  286.  *               rotate to left position.
  287.  */
  288. {
  289. gt_tleft(-degrees);
  290. }
  291.  
  292.  
  293. #if USEVOID
  294. void
  295. #endif
  296. gt_setco(x, y)
  297. int x, y;
  298. /*
  299.  * name          gt_setco
  300.  *
  301.  * synopsis      gt_setco(x, y);
  302.  *               int x,y;     new turtle coordinates.
  303.  *
  304.  * description   This function sets the turtle to the given position. The
  305.  *               position is a turtle graphics coordinate. No line is draw
  306.  *               while repositioning the turtle.
  307.  */
  308. {
  309. clr_turt();  /* erase old turtle */
  310. X = x;
  311. Y = y;
  312. set_turt(); /* mark new turtle position */
  313. }
  314.  
  315.  
  316. int gtgetdir()
  317. /*
  318.  * name          gtgetdir
  319.  *
  320.  * synopsis      degrees = gtgetdir();
  321.  *               int degrees;      current turtle direction in degrees.
  322.  *
  323.  * description   This function returns the current turtle position in degrees.
  324.  *               The returned value will be in range 0 .. 359.
  325.  */
  326. {
  327. int direct;
  328.  
  329. direct = DIR - 90;
  330. return((direct < 0) ? 360 + direct : direct);
  331. }
  332.  
  333.  
  334. #if USEVOID
  335. void
  336. #endif
  337. gt_home()
  338. /*
  339.  * name          gt_home
  340.  *
  341.  * synopsis      gt_home();
  342.  *
  343.  * description   This function sets the turtle to the home position.
  344.  *               After this function call, the turtle will be located
  345.  *               at (0,0) (middle of screen) and points in upward direction.
  346.  */
  347. {
  348. gt_dir(GTDHOME);
  349. gt_setco(GTCO_HX, GTCO_HY);
  350. }
  351.  
  352.  
  353. #if USEVOID
  354. void
  355. #endif
  356. gt_penup()
  357. /*
  358.  * name          gt_penup
  359.  *
  360.  * synopsis      gt_penup();
  361.  *
  362.  * description   This function lifts the turtle pen up, so that no line
  363.  *               will be drawn by further movments. The pen may be lift
  364.  *               down by function gt_pendn.
  365.  *
  366.  * Note          It is not reported as error, if the function is called
  367.  *               while the turtle pen is already lift up.
  368.  */
  369. {
  370. clr_turt();  /* erase old turtle */
  371. turt_pdn = GTP_UP;
  372. set_turt(); /* mark new turtle position */
  373. }
  374.  
  375.  
  376. #if USEVOID
  377. void
  378. #endif
  379. gt_pendn()
  380. /*
  381.  * name          gt_pendn
  382.  *
  383.  * synopsis      gt_pendn();
  384.  *
  385.  * description   This function lifts the turtle pen down, so that a line
  386.  *               will be drawn by further movments. The pen may be lift
  387.  *               up by function gt_penup.
  388.  *
  389.  * Note          It is not reported as error, if the function is called
  390.  *               while the turtle pen is already lift down.
  391.  */
  392. {
  393. clr_turt();  /* erase old turtle */
  394. turt_pdn = GTP_DOWN;
  395. set_turt(); /* mark new turtle position */
  396. }
  397.  
  398.  
  399. #if USEVOID
  400. void
  401. #endif
  402. gt_pcolr(color)
  403. int color;
  404. /*
  405.  * name          gt_pcolr
  406.  *
  407.  * synopsis      gt_pcolr(color);
  408.  *               int color;        new pen color
  409.  *
  410.  * description   This function sets the turtle pen color. All further
  411.  *               drawing will use the specified color.
  412.  *
  413.  * note          The pen status is not modified, so if the pen is lift up,
  414.  *               no drawing will take place.
  415.  *
  416.  */
  417. {
  418. clr_turt();  /* erase old turtle */
  419. COLOR = color;
  420. set_turt(); /* mark new turtle position */
  421. }
  422.  
  423.  
  424. void gt_init()
  425. /*
  426.  * name          gt_init
  427.  *
  428.  * synopsis      gt_init();
  429.  *
  430.  * description   This function initializes the turtle-graphics package.
  431.  *               It clears the graphics screen and initializes the global
  432.  *               to local coordinate system with the default turtle window
  433.  *               size. All turtle parameters are reset to their defaults,
  434.  *               which are as follows:
  435.  *               - turtle position                    (0,0)
  436.  *               - turtle direction                    0
  437.  *               - turtle visible                      no
  438.  *               - turtle delay                        none
  439.  *               - turtle window                       -400,200,400,-200
  440.  *               - turtle pen up                       no
  441.  *               - turtle pen color                    1
  442.  *
  443.  * Note          This function MUST be called before any other turtle
  444.  *               graphics function. If it's not called, the other function
  445.  *               may crash. This function MAY be called at any time to reset
  446.  *               the turtle graphics system.
  447.  */
  448. {
  449. setgloco(-400.0, 200.0, 400.0, -200.0);
  450. DIR = GTDHOME;
  451. gt_pendn();
  452. set_turt();
  453. }
  454.  
  455.  
  456. #if USEVOID
  457. void
  458. #endif
  459. gt_usrmv(speedtab)
  460. int *speedtab;
  461. /*
  462.  * name          gt_usrmv
  463.  *
  464.  * synopsis      gt_usrmv(speedtab);
  465.  *               int *speedtab;      speed table for moves.
  466.  *
  467.  * description   This function allowes it the program to give the user
  468.  *               control over turtle movment. The function accepts single
  469.  *               keystroke commands. The commands are not echoed.
  470.  *               The caller may supply a table of speed values for each
  471.  *               supported speed (0 .. 9). This table consists of 10
  472.  *               int-type entries, which holds the movement entity in the
  473.  *               selected speed. If the user wishes to use the default
  474.  *               speed table, he must supply a NULL pointer.
  475.  *               Commands available:
  476.  *               0 .. 9 : select turtle speed.
  477.  *               n      : turtle direction north
  478.  *               e      : turtle direction east
  479.  *               w      : turtle direction west
  480.  *               s      : turtle direction south
  481.  *               h      : home turtle
  482.  *               b      : move turtle backward
  483.  *               f      : move turtle forward
  484.  *               l      : turn turtle left 1 degree
  485.  *               L      : turn turtle left 5 degrees
  486.  *               r      : turn turtle right 1 degree
  487.  *               R      : turn turtle right 5 degrees
  488.  *               g      : go, change no direction
  489.  *               q      : quit this function
  490.  *
  491.  * note          The turtle system must be initialized before calling this
  492.  *               function. The current state of the turtle system is not
  493.  *               altered before execution, so all parameters are as set by
  494.  *               you.
  495.  */
  496. {
  497. #define NORTH   'n'
  498. #define EAST    'e'
  499. #define WEST    'w'
  500. #define SOUTH   's'
  501. #define HOME    'h'
  502. #define BACKW   'b'
  503. #define FORWD   'f'
  504. #define LEFT1   'l'
  505. #define LEFT5   'L'
  506. #define RIGHT1  'r'
  507. #define RIGHT5  'R'
  508. #define GO      'g'
  509. #define QUIT    'q'
  510.  
  511. static int defspeed[] = {   1,         /* 0 */
  512.                             5,         /* 1 */
  513.                            10,         /* 2 */
  514.                            20,         /* 3 */
  515.                            30,         /* 4 */
  516.                            40,         /* 5 */
  517.                            50,         /* 6 */
  518.                            75,         /* 7 */
  519.                           100,         /* 8 */
  520.                           150          /* 9 */
  521.                           }; /* default speeds */
  522. int curspeed;      /* current speed */
  523. int c;             /* input character (command) */
  524. int turt_fwd = 1;  /* move turtle in forward direction? */
  525. int do_move = -1;  /* move at loop end? */
  526.  
  527. if(speedtab == NULL)
  528.  speedtab = defspeed;
  529. curspeed = *(speedtab + 2);
  530. for(c = getch() ; c != QUIT ; c = getch(), do_move = -1)
  531.   {
  532.   switch(c)
  533.     {
  534.     case '0'      :
  535.     case '1'      :
  536.     case '2'      :
  537.     case '3'      :
  538.     case '4'      :
  539.     case '5'      :
  540.     case '6'      :
  541.     case '7'      :
  542.     case '8'      :
  543.     case '9'      : curspeed = *(speedtab + c - '0');
  544.                     /*
  545.                      * caution: The above conversion is only valid in
  546.                      *          the ASCII alphabet!
  547.                      */
  548.                     do_move = 0;
  549.                     break;
  550.     case NORTH    : gt_dir(GTDNORTH);
  551.                     break;
  552.     case EAST     : gt_dir(GTDEAST);
  553.                     break;
  554.     case WEST     : gt_dir(GTDWEST);
  555.                     break;
  556.     case SOUTH    : gt_dir(GTDSOUTH);
  557.                     break;
  558.     case HOME     : gt_home();
  559.                     break;
  560.     case BACKW    : turt_fwd = 0;
  561.                     break;
  562.     case FORWD    : turt_fwd = 1;
  563.                     break;
  564.     case LEFT1    : gt_tleft(1);
  565.                     do_move = 0;
  566.                     break;
  567.     case LEFT5    : gt_tleft(5);
  568.                     do_move = 0;
  569.                     break;
  570.     case RIGHT1   : gt_trght(1);
  571.                     do_move = 0;
  572.                     break;
  573.     case RIGHT5   : gt_trght(5);
  574.                     do_move = 0;
  575.                     break;
  576.     case GO       : /* nothing to do */
  577.                     break;
  578.     default       : /* unrecogniced command - ignore it */
  579.                     do_move = 0;
  580.                     break;
  581.     }  /* end switch */
  582.   if(do_move)
  583.     gt_forwd(turt_fwd ? curspeed : -curspeed);
  584.   }  /* end main loop (for(..;c != QUIT;..) */
  585. }
  586.  
  587. /*
  588.  * vi mode lines - do not remove!
  589.  *
  590.  * vi: set noic | set sw=2 :
  591.  */
  592.